package de.slothsoft.commons.swing;

import java.lang.reflect.Method;

public final class PropertyUtil {

    public static final String GETTER = "get";
    public static final String IS_GETTER = "is";
    public static final String SETTER = "set";

    public static final <T> void invokeSetter(final Object model, final String property, T value)
	    throws DataBindingException {
	if (value == null) {
	    throw new DataBindingException("If value is null, you have to define the class!");
	}
	invokeSetter(model, property, value, value.getClass());
    }

    public static final void invokeSetter(final Object model, final String property, Object value, Class<?> valueClass)
	    throws DataBindingException {
	try {
	    Method setter = getSetter(model.getClass(), property, valueClass);
	    setter.invoke(model, value);
	} catch (Exception e) {
	    throw new DataBindingException(e);
	}
    }

    public static final Method getSetter(final Class<?> clazz, final String property, Class<?> valueClass)
	    throws DataBindingException {
	try {
	    return clazz.getMethod(SETTER + property, valueClass);
	} catch (Exception e) {
	    throw new DataBindingException(e);
	}
    }

    @SuppressWarnings("unchecked")
    public static final <T> T invokeGetter(final Object model, final String property) throws DataBindingException {
	try {
	    Method getter = getGetter(model.getClass(), property);
	    return (T) getter.invoke(model);
	} catch (Exception e) {
	    throw new DataBindingException(e);
	}
    }

    public static final Method getGetter(final Class<?> clazz, final String property) throws DataBindingException {
	try {
	    try {
		return clazz.getMethod(IS_GETTER + property);
	    } catch (Exception e) {
		// if this did not work, the getter might not be isBoolean
		return clazz.getMethod(GETTER + property);
	    }
	} catch (Exception e) {
	    throw new DataBindingException(e);
	}
    }

    private PropertyUtil() {
	// *hides*
    }
}
